package com.itlong.cloud.operate.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.operate.OperateRenewManageGetDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyInvoiceInfoDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.operate.OperateBusinessOperationLogVO;
import com.itlong.cloud.POJO.VO.operate.OperateRenewManageGetVO;
import com.itlong.cloud.POJO.VO.property.PropertyInvoiceInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.commons.dao.IPaymentTradeDao;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.OperateRenewManageOperationFunctionEnum;
import com.itlong.cloud.enumerate.SmartCommunityEnum;
import com.itlong.cloud.operate.dao.IOperateBusinessChargeDao;
import com.itlong.cloud.operate.dao.IOperateRenewManageDao;
import com.itlong.cloud.operate.service.IOperateRenewManageService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <desc>
 *      运营-财务续费管理服务层接口实现类
 * </desc>
 *
 * @createDate 2019/08/05
 */
@Service
public class OperateRenewManageServiceImpl implements IOperateRenewManageService {

    @Autowired
    private IOperateRenewManageDao iOperateRenewManageDao;

    @Autowired
    private IOperateBusinessChargeDao iOperateBusinessChargeDao;

    @Autowired
    private IPaymentTradeDao iWechatPayDao;

    @Autowired
    private MessageSender messageSender;

    /**
     * <desc>
     *      分页获取财务续费信息
     * </desc>
     *
     * @param operateRenewManageGetDTO 获取财务续费信息DTO
     * @return 分页财务续费信息
     * @author wangzhi
     * @createDate 2019/08/05
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<OperateRenewManageGetVO> getPage(OperateRenewManageGetDTO operateRenewManageGetDTO) throws Exception {
        if(StringUtils.isEmpty(operateRenewManageGetDTO.getOrderColumn()) || StringUtils.isEmpty(operateRenewManageGetDTO.getOrderRule())){
            operateRenewManageGetDTO.setOrderColumn("createTime");
            operateRenewManageGetDTO.setOrderRule("DESC");
        }
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(operateRenewManageGetDTO);
        Page<OperateRenewManageGetVO> page = new Page<>();
        page.getPage().setPageSize(operateRenewManageGetDTO.getPageSize());
        page.getPage().setCurrentPage(operateRenewManageGetDTO.getCurrentPage());
        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        List<OperateRenewManageGetVO> operateRenewManageGetVOList = iOperateRenewManageDao.getPage(params);
        page.setRows(operateRenewManageGetVOList, iOperateRenewManageDao.getRecordCount(params));
        return page;
    }

    /**
     * <desc>
     *      获取财务续费信息总金额
     * </desc>
     *
     * @param operateRenewManageGetDTO 财务续费审批DTO
     * @return 财务续费信息总金额
     * @author wangzhi
     * @createDate 2019/08/07
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public String getTotalAmount(OperateRenewManageGetDTO operateRenewManageGetDTO) throws Exception {
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(operateRenewManageGetDTO);
        return iOperateRenewManageDao.getTotalAmount(params);
    }

    /**
     * <desc>
     *      获取财务续费信息详情
     * </desc>
     *
     * @param operateRenewManageGetDTO 获取财务续费信息DTO
     * @return 财务续费信息详情
     * @author wangzhi
     * @createDate 2019/08/05
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public OperateRenewManageGetVO getOne(OperateRenewManageGetDTO operateRenewManageGetDTO) throws Exception {
         return iOperateRenewManageDao.getOne(operateRenewManageGetDTO);
    }

    /**
     * <desc>
     *      财务续费收款确认
     * </desc>
     *
     * @param operateRenewManageGetDTO
     * @return  受影响行数
     * @Author Zhu.yj
     * @createDate  2019/11/27
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer confirm(OperateRenewManageGetDTO operateRenewManageGetDTO) throws Exception{
        Date nowTime = new Date();
        String operateName = "";
        Map<String, Object> params = new HashMap<>();
        //审核不通过时将订单状态置为1未支付
        Integer feeStatus = 1;
        //审核通过且支付订单状态未支付
        if (operateRenewManageGetDTO.getConfirmStatus() == 1 && operateRenewManageGetDTO.getFeeStatus() ==1){
            //若审核通过，则将订单支付状态置为已支付
            feeStatus = 2;
            params.put("payTime",nowTime);
            operateName = "收款确认通过,备注:"+operateRenewManageGetDTO.getRemark();
        }
        //审核通过且支付订单状态未为待确认
        if (operateRenewManageGetDTO.getConfirmStatus() ==1 && operateRenewManageGetDTO.getFeeStatus() == 3){
            feeStatus = 2;
            operateName = "收款确认通过,备注:"+operateRenewManageGetDTO.getRemark();
        }
        //收款确认未通过时清除支付时间
        if(operateRenewManageGetDTO.getConfirmStatus() == 2){
            feeStatus = 1;
            params.put("payTime",null);
            operateName = "收款确认未通过,备注:"+operateRenewManageGetDTO.getRemark();
        }
        params.put("orderId",operateRenewManageGetDTO.getOrderId());
        params.put("acceptUser",operateRenewManageGetDTO.getMyUserName());
        params.put("feeStatus",feeStatus);
        params.put("acceptTime",nowTime);
        params.put("updateTime",nowTime);
        params.put("remark",operateRenewManageGetDTO.getRemark());
        iOperateRenewManageDao.updateCloudServiceOrderByConfirm(params);

        OperateUserInfoPO operateUserInfoPO = iOperateBusinessChargeDao.getOperateUserPO(operateRenewManageGetDTO.getMyUserName());
        OperationSpecialLogPO operationSpecialLogPO = new OperationSpecialLogPO();
        operationSpecialLogPO.setLogId(LogicIdUtil.bussinessId());
        operationSpecialLogPO.setRealName(operateUserInfoPO.getRealName());
        operationSpecialLogPO.setAccount(operateUserInfoPO.getUserName());
        operationSpecialLogPO.setOuterId(operateRenewManageGetDTO.getOrderId());
        operationSpecialLogPO.setIp(operateRenewManageGetDTO.getIp());
        operationSpecialLogPO.setOperateFunction(operateRenewManageGetDTO.getOperateFunction());
        operationSpecialLogPO.setOperateWay(operateRenewManageGetDTO.getOperateWay());
        operationSpecialLogPO.setFunctionType(2);
        operationSpecialLogPO.setOperateDec(operateUserInfoPO.getRealName()+operateName);
        operationSpecialLogPO.setStatus(DataStatusEnum.NORMAL.getType());
        operationSpecialLogPO.setCreateTime(nowTime);
        operationSpecialLogPO.setUpdateTime(nowTime);
        iOperateBusinessChargeDao.save(SqlUtil.durableData(operationSpecialLogPO,PlatformConstants.TABLE_SAVE));
        return 1;
    }

    /**
     * <desc>
     *      财务续费审批
     * </desc>
     *
     * @param operateRenewManageGetDTO 财务续费审批DTO
     * @return 1成功 0失败
     * @author wangzhi
     * @createDate 2019/08/05
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer accept(OperateRenewManageGetDTO operateRenewManageGetDTO) throws Exception {
        List<String> orderIdList = StringHandlerUtil.splitStringList(operateRenewManageGetDTO.getOrderIds());
        Map<String, Object> renewOrderMap = new HashMap<>();
        Date nowTime = new Date();
        Integer acceptStatus = null;
        Integer feeStatus = null;
        String operateName = "";
        // 修改账单状态
        switch (OperateRenewManageOperationFunctionEnum.getByType(operateRenewManageGetDTO.getType())){
            //提交操作
            case FUNCTION_COMMIT:
                operateName = OperateRenewManageOperationFunctionEnum.FUNCTION_COMMIT.getDescription()+"备注:"+operateRenewManageGetDTO.getRemark();
                //将订单审核状态修改为未审核 1.未提交 2未审核 3已审核
                acceptStatus = 2;
                break;
            //撤回操作
            case FUNCTION_WITHDRAW:
                operateName = OperateRenewManageOperationFunctionEnum.FUNCTION_WITHDRAW.getDescription()+"备注:"+operateRenewManageGetDTO.getRemark();
                acceptStatus = 1;
                //需求变更，当订单撤回时，更改订单状态为未支付
                feeStatus = 1;
                break;
            //审核操作，将已提交的订单
            case FUNCTION_ACCEPT:
                operateName = OperateRenewManageOperationFunctionEnum.FUNCTION_ACCEPT.getDescription()+"备注:"+operateRenewManageGetDTO.getRemark();
                acceptStatus = 3;
                break;
            //回退操作，将未审核的订单回退至未提交
            case FUNCTION_UNDO:
                operateName = OperateRenewManageOperationFunctionEnum.FUNCTION_UNDO.getDescription()+"备注:"+operateRenewManageGetDTO.getRemark();
                acceptStatus = 1;
                break;
            //弃审操作，只有已审核的订单可执行此操作，将订单状态更改为未审批
            case FUNCTION_ABANDON:
                operateName = OperateRenewManageOperationFunctionEnum.FUNCTION_ABANDON.getDescription()+"备注:"+operateRenewManageGetDTO.getRemark();
                acceptStatus = 2;
                break;
        }
        renewOrderMap.put("acceptStatus",acceptStatus);
        renewOrderMap.put("feeStatus",feeStatus);
        renewOrderMap.put("updateTime",nowTime);
        renewOrderMap.put("orderIds",orderIdList);
        Integer acceptCount = iOperateRenewManageDao.updateCloudServiceOrderByAccept(renewOrderMap);
        //当操作为审核并且审核成功时才通知云对讲
        if((operateRenewManageGetDTO.getType() == 3 || operateRenewManageGetDTO.getType() == 5) && acceptCount >0 ) {
            //项目云服务费变更后需通知该批次号下的云对讲设备
            String[] orderIds = operateRenewManageGetDTO.getOrderIds().split(",");
            for(String orderId : orderIds){
                List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
                JSONArray jsonArray = new JSONArray();
                List<Map<String, String>> deviceList = iWechatPayDao.getDeviceInfoByBatchNumber(orderId);
                if (deviceList != null && !deviceList.isEmpty()) {
                    List<Map<String, String>> allDeviceList = iWechatPayDao.getCloudTalkInfoByProjectId(deviceList.get(0).get("projectId"));
                    if(allDeviceList != null && !allDeviceList.isEmpty()){
                        for (Map<String, String> map : allDeviceList) {
                            if(StringUtils.isEmpty(map.get("deviceUnique"))){
                                continue;
                            }
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("deviceUnique", map.get("deviceUnique"));
                            jsonArray.add(jsonObject);
                        }
                    }
                    //处理多个批次号复用时合为一个新的批次号的设备批次号信息
                    if (StringUtils.isNotEmpty(deviceList.get(0).get("oldBatchNumber")) && operateRenewManageGetDTO.getType() == 3) {
                        iWechatPayDao.updateElevatorBatchNumber(deviceList.get(0).get("oldBatchNumber").split(","), deviceList.get(0).get("batchNumber"));
                        iWechatPayDao.updateEntranceBatchNumber(deviceList.get(0).get("oldBatchNumber").split(","), deviceList.get(0).get("batchNumber"));
                        iWechatPayDao.updateCloudIntercomBatchNumber(deviceList.get(0).get("oldBatchNumber").split(","), deviceList.get(0).get("batchNumber"));
                        iWechatPayDao.updatePadBatchNumber(deviceList.get(0).get("oldBatchNumber").split(","), deviceList.get(0).get("batchNumber"));
                    }
                }

                //项目云服务费变更后需通知云对讲
                if (!jsonArray.isEmpty()) {
                    DeviceBusinessChangeLogPO changeLogPO = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE, jsonArray, deviceList.get(0).get("projectId"));
                    changeLogPOS.add(changeLogPO);
                }
                //向设备推送设备云对讲指令
                if (!changeLogPOS.isEmpty()) {
                    JSONObject dataJs = new JSONObject();
                    dataJs.put("data", changeLogPOS);
                    //云对讲
                    messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                            JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                }
            }
        }

        OperateUserInfoPO operateUserInfoPO = iOperateBusinessChargeDao.getOperateUserPO(operateRenewManageGetDTO.getMyUserName());
        List<OperationSpecialLogPO> operationSpecialLogPOList = new ArrayList<>();
        for (String orderId:orderIdList) {
            OperationSpecialLogPO operationSpecialLogPO = new OperationSpecialLogPO();
            operationSpecialLogPO.setLogId(LogicIdUtil.bussinessId());
            operationSpecialLogPO.setRealName(operateUserInfoPO.getRealName());
            operationSpecialLogPO.setAccount(operateUserInfoPO.getUserName());
            operationSpecialLogPO.setOuterId(orderId);
            operationSpecialLogPO.setIp(operateRenewManageGetDTO.getIp());
            operationSpecialLogPO.setOperateFunction(operateRenewManageGetDTO.getOperateFunction());
            operationSpecialLogPO.setOperateWay(operateRenewManageGetDTO.getOperateWay());
            operationSpecialLogPO.setFunctionType(2);
            operationSpecialLogPO.setOperateDec(operateUserInfoPO.getRealName()+""+operateName);
            operationSpecialLogPO.setStatus(DataStatusEnum.NORMAL.getType());
            operationSpecialLogPO.setCreateTime(nowTime);
            operationSpecialLogPO.setUpdateTime(nowTime);
            operationSpecialLogPOList.add(operationSpecialLogPO);
        }
        iOperateBusinessChargeDao.batchSaveOperationLogData(operationSpecialLogPOList);
        return acceptCount;
}

    /**
     * <desc>
     *      获取财务续费附加信息
     * </desc>
     *
     * @param operateRenewManageGetDTO 财务续费DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2019/11/21
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Map<String, Object> getAppendInfo(OperateRenewManageGetDTO operateRenewManageGetDTO) throws Exception{
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(operateRenewManageGetDTO);
        Map<String,Object> data = new HashMap<>();
        //计算财务续费账单未提交数量
        params.put("acceptStatus",1);
        Integer unCommitCount = iOperateRenewManageDao.getRecordCount(params);
        //计算财务续费账单未审核的数量
        params.put("acceptStatus",2);
        Integer unAcceptCount = iOperateRenewManageDao.getRecordCount(params);
        //计算财务续费账单已审核的数量
        params.put("acceptStatus",3);
        Integer acceptedCount = iOperateRenewManageDao.getRecordCount(params);

        params.remove("acceptStatus");
        //计算待确认的数量 feeStatus为3时订单状态为待确认
        params.put("feeStatus",3);
        Integer toBeConfirmedCount = iOperateRenewManageDao.getRecordCount(params);
        //计算待开票数量 billingStatus为3时订单状态为待开票
        params.put("feeStatus",operateRenewManageGetDTO.getFeeStatus());
        params.put("billingStatus",3);
        Integer toBeBilledCount = iOperateRenewManageDao.getRecordCount(params);
        data.put("unCommitCount",unCommitCount);
        data.put("unAcceptCount",unAcceptCount);
        data.put("acceptedCount",acceptedCount);
        data.put("toBeConfirmedCount",toBeConfirmedCount);
        data.put("toBeBilledCount",toBeBilledCount);
        return data;
    }

    /**
     * <desc>
     *      获取发票信息
     * </desc>
     *
     * @param operateRenewManageGetDTO 发票信息DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2019/11/22
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyInvoiceInfoVO getBillInfo(OperateRenewManageGetDTO operateRenewManageGetDTO) throws Exception{
        PropertyInvoiceInfoVO propertyInvoiceInfoVO = iOperateRenewManageDao.getBillInfo(operateRenewManageGetDTO);
        //将前端传的orderId添加进VO返回
        propertyInvoiceInfoVO.setOrderId(operateRenewManageGetDTO.getOrderId());
        return propertyInvoiceInfoVO;
    }

    /**
     * <desc>
     *      开票
     * </desc>
     *
     * @param propertyInvoiceInfoDTO 待开发票信息
     * @return
     * @Author Zhu.yj
     * @createDate  2019/11/25
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer billing(PropertyInvoiceInfoDTO propertyInvoiceInfoDTO) throws Exception{
        Date nowTime = new Date();
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(propertyInvoiceInfoDTO);
        params.put("updateTime",nowTime);
        //更新发票信息表中信息
        iOperateRenewManageDao.updateInvoiceByConfirm(params);

        //开票成功，将订单的开票状态置为已开票
        Map<String, Object> renewBillMap = new HashMap<>();
        renewBillMap.put("updateTime",nowTime);
        //2为已开票
        renewBillMap.put("billingStatus",2);
        renewBillMap.put("orderId",propertyInvoiceInfoDTO.getOrderId());
        iOperateRenewManageDao.updateBillingStatus(renewBillMap);

        OperateUserInfoPO operateUserInfoPO = iOperateBusinessChargeDao.getOperateUserPO(propertyInvoiceInfoDTO.getMyUserName());
        OperationSpecialLogPO operationSpecialLogPO = new OperationSpecialLogPO();
        operationSpecialLogPO.setLogId(LogicIdUtil.bussinessId());
        operationSpecialLogPO.setAccount(operateUserInfoPO.getUserName());
        operationSpecialLogPO.setRealName(operateUserInfoPO.getRealName());
        operationSpecialLogPO.setOuterId(propertyInvoiceInfoDTO.getOrderId());
        operationSpecialLogPO.setIp(propertyInvoiceInfoDTO.getIp());
        operationSpecialLogPO.setFunctionType(2);
        operationSpecialLogPO.setOperateFunction(propertyInvoiceInfoDTO.getOperateFunction());
        operationSpecialLogPO.setOperateWay(propertyInvoiceInfoDTO.getOperateWay());
        operationSpecialLogPO.setOperateDec(operateUserInfoPO.getRealName()+"开具发票");
        operationSpecialLogPO.setStatus(DataStatusEnum.NORMAL.getType());
        operationSpecialLogPO.setCreateTime(nowTime);
        operationSpecialLogPO.setUpdateTime(nowTime);
        iOperateRenewManageDao.save(SqlUtil.durableData(operationSpecialLogPO,PlatformConstants.TABLE_SAVE));

        return 1;
    }

    /**
     * <desc>
     *      获取财务续费订单业务日志
     * </desc>
     *
     * @param operateRenewManageGetDTO
     * @return
     * @Author Zhu.yj
     * @createDate  2019/11/27
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<OperateBusinessOperationLogVO> getLogPage(OperateRenewManageGetDTO operateRenewManageGetDTO) throws Exception {
        if(StringUtils.isEmpty(operateRenewManageGetDTO.getOrderColumn()) || StringUtils.isEmpty(operateRenewManageGetDTO.getOrderRule())){
            operateRenewManageGetDTO.setOrderColumn("createTime");
            operateRenewManageGetDTO.setOrderRule("DESC");
        }
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(operateRenewManageGetDTO);
        Page<OperateBusinessOperationLogVO> page = new Page<>();
        page.getPage().setPageSize(operateRenewManageGetDTO.getPageSize());
        page.getPage().setCurrentPage(operateRenewManageGetDTO.getCurrentPage());
        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        List<OperateBusinessOperationLogVO> operateBusinessOperationLogVOS = iOperateRenewManageDao.getLogPage(params);
        page.setRows(operateBusinessOperationLogVOS,iOperateRenewManageDao.getLogPageCount(params));
        return page;
    }
}
